package view.accciones;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JDialog;
import javax.swing.JOptionPane;

import utils.Mensaje;
import utils.Parseador;
import view.Pantalla;

import model.Atributo;
import model.AtributoCompuesto;
import model.Entidad;
import model.Jerarquia;
import model.Relacion;
import constants.DiagramaConstants;
import controller.ManagerProyecto;

public class EliminarAction  extends JDialog{

	private static final long serialVersionUID = 1L;
	
	private ManagerProyecto controlProyecto;
	private String nombreElemento;
	private String tipoElemento;
	private String reference;
	private static EliminarAction singleton;
	private boolean eliminarEntidadGlobal;

	public void mostrarMensajeEliminacionEdges(){
		JOptionPane.showMessageDialog(this,Mensaje.ELIMINAR_EDGES, "Eliminar Conexiones",
                JOptionPane.INFORMATION_MESSAGE);
	}
	
	public void setEliminarEntidadGlobal(boolean eliminarEntidadGlobal) {
		this.eliminarEntidadGlobal = eliminarEntidadGlobal;
	}

	private EliminarAction(){
		this.controlProyecto = ManagerProyecto.getInstance();
		this.eliminarEntidadGlobal = false;
	}
	
	public static EliminarAction getInstance(){
		if(singleton == null){
			singleton = new EliminarAction();
		}
		
		return singleton;
	}
	
	public String getNombreElemento() {
		return nombreElemento;
	}


	public void setNombreElemento(String nombreElemento) {
		this.nombreElemento = nombreElemento;
	}
	
	
	public String getTipoElemento() {
		return tipoElemento;
	}


	public void setTipoElemento(String tipoElemento) {
		this.tipoElemento = tipoElemento;
	}


	public void eliminar(){
		if(tipoElemento.equals(DiagramaConstants.ENTIDAD)){
			this.eliminarEntidad(nombreElemento);
			Pantalla p = Pantalla.getPantalla();
			p.getPackageExplorer().actualizar(this.controlProyecto.getProyecto().getIdentificator(),
					this.controlProyecto.getProyecto().getListaDiagramas(),
					this.controlProyecto.getDiagramaEnPantalla().getIdentificator(), this.controlProyecto.getDiagramaEnPantalla().getListaEntidades());
			
		}else if(tipoElemento.equals(DiagramaConstants.RELACION)){
			this.eliminarRelacion(nombreElemento);
			
		}else if(tipoElemento.equals(DiagramaConstants.ATRIBUTO_COMPUESTO) || tipoElemento.equals(DiagramaConstants.ATRIBUTO) ){
			this.eliminarAtributo();
			
		}else if(tipoElemento.equals(DiagramaConstants.JERARQUIA)){
			this.eliminarJerarquia();
		}
			
		
	}
	
	//al eliminar una entidad del diagrama se deben eliminar ademas todas las relaciones y jerarquias que tengan a esta entidad 
	private void eliminarEntidad(String nombreElemento) {
		
		//elimino las relaciones del diagrama que contengan a la entidad que se esta eliminando
		List<Relacion> listaRelaciones = controlProyecto.getDiagramaEnPantalla().getListaRelaciones();
		List<Relacion> listaRelacionesAEliminar = new ArrayList<Relacion>();
		
		Iterator<Relacion> itRelaciones = listaRelaciones.iterator();
		
		while(itRelaciones.hasNext()){
			Relacion relacion = itRelaciones.next();
			
			if(relacion.getListaEntidades().contains(nombreElemento)){
				listaRelacionesAEliminar.add(relacion);
				
			}
		}
		
		itRelaciones = listaRelacionesAEliminar.iterator();
		
		while(itRelaciones.hasNext()){
			Relacion re = itRelaciones.next();
			
			controlProyecto.getDiagramaEnPantalla().getListaRelaciones().remove(re);
		}
		
		
		//elimino las jerarquias del diagrama que contengan a la entidad que se esta eliminando
		List<Jerarquia> listaJerarquias = controlProyecto.getDiagramaEnPantalla().getListaJerarquia();
		List<Jerarquia> listaJerarquiasAEliminar = new ArrayList<Jerarquia>();
		
		Iterator<Jerarquia> itJerarquias = listaJerarquias.iterator();
		
		while(itJerarquias.hasNext()){
			Jerarquia jerarquia = itJerarquias.next();
			
			if(jerarquia.getEntidadGeneral().equals(nombreElemento) 
					|| jerarquia.getListadeEntidadesEspecializadas().contains(nombreElemento)){
				listaJerarquiasAEliminar.add(jerarquia);
				
			}
		}
		
		itJerarquias = listaJerarquiasAEliminar.iterator();
		
		while(itJerarquias.hasNext()){
			Jerarquia jer = itJerarquias.next();
			
			controlProyecto.getDiagramaEnPantalla().getListaJerarquia().remove(jer);
		}
		
		//elimino la entidad de la lista de entidades del diagrama
		controlProyecto.getDiagramaEnPantalla().getListaEntidades().remove(nombreElemento);
		
		//veo si tengo que eliminar la entidad en forma global
		if(this.eliminarEntidadGlobal){
		
			List<Entidad> listaEntidadesDelProyecto = controlProyecto.getProyecto().getListaEntidades();
			
			for(Entidad entidad : listaEntidadesDelProyecto){
				if(entidad.getIdentificator().equals(nombreElemento)){
					listaEntidadesDelProyecto.remove(entidad);
					break;
					
				}
			}
			
		}
		
	}
	
	//elimina la relacion de la lista de relaciones del diagrama
	private void eliminarRelacion(String nombreElemento) {
		
		int posicionRelacion = -1;
		List<Relacion> listaRelaciones = controlProyecto.getDiagramaEnPantalla().getListaRelaciones();
		
		for(int i=0; i<listaRelaciones.size(); i++){
			if(listaRelaciones.get(i).getIdentificator().equals(nombreElemento)){
				posicionRelacion = i;
			}
		}
		
		controlProyecto.getDiagramaEnPantalla().getListaRelaciones().remove(posicionRelacion);
		
	}

	
	//elimina el atributo 
	private void eliminarAtributo(){
		
		int posicionAtributoSimple = -1;
		int posicionAtributoCompuesto = -1;
		int i = 0;
		int j = 0;
		int k = 0;
		
		List<String> listaReferencia = Parseador.obtenerElementoOrigenDelAtributo(reference);
		
		
		//el atributo es de una entidad
		if(listaReferencia.get(0).equals("Entidad")){
			
			List<Entidad> listaEntidades = controlProyecto.getProyecto().getListaEntidades();
			Iterator<Entidad> it = listaEntidades.iterator();
			
			//obtengo las entidades del proyecto
			while(it.hasNext()){
				Entidad entidad = it.next();
				
				if(entidad.getIdentificator().equals(listaReferencia.get(1))){
					
					
					//me fijo si el atributo a eliminar es Simple
					if(listaReferencia.get(listaReferencia.size()-2).equals("Simple")){
						
						System.out.println("Se elimina atributo simple");
						
						//Entidad:nombreEntidad.Simple:nombreAtributo
						if(listaReferencia.size() == 4){
							
							System.out.println("Caso " + reference);
							
							//obtengo la lista de atributos simples de la entidad de referencia
							List<Atributo> listaAtributo = entidad.getListaAtributos();
							
							for(i=0; i<listaAtributo.size(); i++){
								if(listaAtributo.get(i).getNombre().equals(listaReferencia.get(3))){
									posicionAtributoSimple = i;
								}
							}
							
							entidad.getListaAtributos().remove(posicionAtributoSimple);
							
							
						//Entidad:nombreEntidad.Compuesto:nombreAtributoCompuestoPrimerNivel.Simple:nombreAtributo
						}else if(listaReferencia.size() == 6){
							
							System.out.println("Caso "+reference);
							
							//obtengo la lista de atributos simples de la lista de atributos compuestos de la entidad de referencia
							List<AtributoCompuesto> listaAtributoCompuestoPrimerNivel = entidad.getListaAtributosCompuestos();
							
							for(i=0; i<listaAtributoCompuestoPrimerNivel.size(); i++){
								AtributoCompuesto atributoCompuesto = listaAtributoCompuestoPrimerNivel.get(i);
								
								if(atributoCompuesto.getNombre().equals(listaReferencia.get(3))){
									
									List<Atributo> listaAtributoSimple = atributoCompuesto.getListaAtributos();
									
									for(j=0; j<listaAtributoSimple.size(); j++){
										if(listaAtributoSimple.get(j).getNombre().equals(listaReferencia.get(5))){
											posicionAtributoSimple = j;
											
										}
									}
									
									listaAtributoSimple.remove(posicionAtributoSimple);
									
								}

							}

						//Entidad:nombreEntidad.Compuesto:nombreAtributoCompuestoPrimerNivel.Compuesto:nombreAtributoCompuestoSegundoNivel.Simple:nombreAtributo
						}else if(listaReferencia.size() == 8){
							
							System.out.println("Caso "+reference);
							
							/*obtengo la lista de atributos simples de la lista de atributos compuestos de la lista de atributos compuestos de 
							 * la entidad de referencia.
							 */
							List<AtributoCompuesto> listaAtributoCompuestoPrimerNivel = entidad.getListaAtributosCompuestos();
							
							for(i=0; i<listaAtributoCompuestoPrimerNivel.size(); i++){
								AtributoCompuesto atributoCompuestoPrimerNivel = listaAtributoCompuestoPrimerNivel.get(i);
								
								if(atributoCompuestoPrimerNivel.getNombre().equals(listaReferencia.get(3))){
									
									List<AtributoCompuesto> listaAtributoCompuestoSegundoNivel = atributoCompuestoPrimerNivel.getListaAtributosCompuestos();
									
									for(j=0; j<listaAtributoCompuestoSegundoNivel.size(); j++){
										AtributoCompuesto atributoCompuestoSegundoNivel = listaAtributoCompuestoPrimerNivel.get(i);
										
										if(atributoCompuestoSegundoNivel.getNombre().equals(listaReferencia.get(5))){
											List<Atributo> listaAtributoSimple = atributoCompuestoSegundoNivel.getListaAtributos();
											
											for(k=0; k<listaAtributoSimple.size(); k++){
												if(listaAtributoSimple.get(k).getNombre().equals(listaReferencia.get(7))){
													posicionAtributoSimple = k;
													
												}
											}
											
											listaAtributoSimple.remove(posicionAtributoSimple);
											
										}
										
									}
								}
							}
						}
						
					//me fijo si el atributo a eliminar es Compuesto
					}else if(listaReferencia.get(listaReferencia.size()-2).equals("Compuesto")){
						
						System.out.println("Se elimina atributo compuesto");
						
						//Entidad:nombreEntidad.Compuesto:nombreAtributoCompuestoPrimerNivel
						if(listaReferencia.size() == 4){
							
							System.out.println("Caso "+reference);
							
							//obtengo la lista de atributos compuestos de la entidad de referencia
							List<AtributoCompuesto> listaAtributoCompuestosPrimerNivel = entidad.getListaAtributosCompuestos();
							
							for(i=0; i<listaAtributoCompuestosPrimerNivel.size(); i++){
								if(listaAtributoCompuestosPrimerNivel.get(i).getNombre().equals(listaReferencia.get(3))){
									posicionAtributoCompuesto = i;
								}
							}
							
							listaAtributoCompuestosPrimerNivel.remove(posicionAtributoCompuesto);
							
						//Entidad:nombreEntidad.Compuesto:nombreAtributoCompuestoPrimerNivel.Compuesto:nombreAtributoCompuestoSegundoNivel
						}else if(listaReferencia.size() == 6){
							
							System.out.println("Caso "+reference);
							
							//obtengo la lista de atributos compuestos de la entidad de referencia
							List<AtributoCompuesto> listaAtributoCompuestosPrimerNivel = entidad.getListaAtributosCompuestos();
							
							for(i=0; i<listaAtributoCompuestosPrimerNivel.size(); i++){
								if(listaAtributoCompuestosPrimerNivel.get(i).getNombre().equals(listaReferencia.get(3))){
									
									List<AtributoCompuesto> listaAtributoCompuestosSegundoNivel = listaAtributoCompuestosPrimerNivel.get(i).getListaAtributosCompuestos();
									
									for(j=0; j<listaAtributoCompuestosPrimerNivel.size(); j++){
										if(listaAtributoCompuestosSegundoNivel.get(j).getNombre().equals(listaReferencia.get(3))){
											posicionAtributoCompuesto = j;
										}
									}
									
									listaAtributoCompuestosSegundoNivel.remove(posicionAtributoCompuesto);
								}
							}
						}
				
					}
				}
			}
			
		//el atributo es de una relacion
		}else if(listaReferencia.get(0).equals("Relacion")){
			
			List<Relacion> listaRelaciones = controlProyecto.getDiagramaEnPantalla().getListaRelaciones();
			Iterator<Relacion> it = listaRelaciones.iterator();
			
			//obtengo las entidades del proyecto
			while(it.hasNext()){
				Relacion relacion = it.next();
				
				if(relacion.getIdentificator().equals(listaReferencia.get(1))){
					
					
					//me fijo si el atributo a eliminar es Simple
					if(listaReferencia.get(listaReferencia.size()-2).equals("Simple")){
						
						System.out.println("Se elimina atributo simple");
						
						//Relacion:nombreRelacion.Simple:nombreAtributo
						if(listaReferencia.size() == 4){
							
							System.out.println("Caso "+reference);
							
							//obtengo la lista de atributos simples de la entidad de referencia
							List<Atributo> listaAtributo = relacion.getListaAtributos();
							
							for(i=0; i<listaAtributo.size(); i++){
								if(listaAtributo.get(i).getNombre().equals(listaReferencia.get(3))){
									posicionAtributoSimple = i;
								}
							}
							
							relacion.getListaAtributos().remove(posicionAtributoSimple);
							
							
						//Relacion:nombreRelacion.Compuesto:nombreAtributoCompuestoPrimerNivel.Simple:nombreAtributo
						}else if(listaReferencia.size() == 6){
							
							System.out.println("Caso "+reference);
							
							//obtengo la lista de atributos simples de la lista de atributos compuestos de la entidad de referencia
							List<AtributoCompuesto> listaAtributoCompuestoPrimerNivel = relacion.getListaAtributosCompuestos();
							
							for(i=0; i<listaAtributoCompuestoPrimerNivel.size(); i++){
								AtributoCompuesto atributoCompuesto = listaAtributoCompuestoPrimerNivel.get(i);
								
								if(atributoCompuesto.getNombre().equals(listaReferencia.get(3))){
									
									List<Atributo> listaAtributoSimple = atributoCompuesto.getListaAtributos();
									
									for(j=0; j<listaAtributoSimple.size(); j++){
										if(listaAtributoSimple.get(j).getNombre().equals(listaReferencia.get(5))){
											posicionAtributoSimple = j;
											
										}
									}
									
									listaAtributoSimple.remove(posicionAtributoSimple);
									
								}

							}

						//Relacion:nombreRelacion.Compuesto:nombreAtributoCompuestoPrimerNivel.Compuesto:nombreAtributoCompuestoSegundoNivel.Simple:nombreAtributo
						}else if(listaReferencia.size() == 8){
							
							System.out.println("Caso "+reference);
							
							/*obtengo la lista de atributos simples de la lista de atributos compuestos de la lista de atributos compuestos de 
							 * la entidad de referencia.
							 */
							List<AtributoCompuesto> listaAtributoCompuestoPrimerNivel = relacion.getListaAtributosCompuestos();
							
							for(i=0; i<listaAtributoCompuestoPrimerNivel.size(); i++){
								AtributoCompuesto atributoCompuestoPrimerNivel = listaAtributoCompuestoPrimerNivel.get(i);
								
								if(atributoCompuestoPrimerNivel.getNombre().equals(listaReferencia.get(3))){
									
									List<AtributoCompuesto> listaAtributoCompuestoSegundoNivel = atributoCompuestoPrimerNivel.getListaAtributosCompuestos();
									
									for(j=0; j<listaAtributoCompuestoSegundoNivel.size(); j++){
										AtributoCompuesto atributoCompuestoSegundoNivel = listaAtributoCompuestoPrimerNivel.get(i);
										
										if(atributoCompuestoSegundoNivel.getNombre().equals(listaReferencia.get(5))){
											List<Atributo> listaAtributoSimple = atributoCompuestoSegundoNivel.getListaAtributos();
											
											for(k=0; k<listaAtributoSimple.size(); k++){
												if(listaAtributoSimple.get(k).getNombre().equals(listaReferencia.get(7))){
													posicionAtributoSimple = k;
													
												}
											}
											
											listaAtributoSimple.remove(posicionAtributoSimple);
											
										}
										
									}
								}
							}
						}
						
						
					//me fijo si el atributo a eliminar es Compuesto
					}else if(listaReferencia.get(listaReferencia.size()-2).equals("Compuesto")){
						
						System.out.println("Se elimina atributo compuesto");
						
						//Relacion:nombreRelacion.Compuesto:nombreAtributoCompuestoPrimerNivel
						if(listaReferencia.size() == 4){
							
							System.out.println("Caso "+reference);
							
							//obtengo la lista de atributos compuestos de la entidad de referencia
							List<AtributoCompuesto> listaAtributoCompuestosPrimerNivel = relacion.getListaAtributosCompuestos();
							
							for(i=0; i<listaAtributoCompuestosPrimerNivel.size(); i++){
								if(listaAtributoCompuestosPrimerNivel.get(i).getNombre().equals(listaReferencia.get(3))){
									posicionAtributoCompuesto = i;
								}
							}
							
							listaAtributoCompuestosPrimerNivel.remove(posicionAtributoCompuesto);
							
						//Relacion:nombreRelacion.Compuesto:nombreAtributoCompuestoPrimerNivel.Compuesto:nombreAtributoCompuestoSegundoNivel
						}else if(listaReferencia.size() == 6){
							
							System.out.println("Caso "+reference);
							
							//obtengo la lista de atributos compuestos de la entidad de referencia
							List<AtributoCompuesto> listaAtributoCompuestosPrimerNivel = relacion.getListaAtributosCompuestos();
							
							for(i=0; i<listaAtributoCompuestosPrimerNivel.size(); i++){
								if(listaAtributoCompuestosPrimerNivel.get(i).getNombre().equals(listaReferencia.get(3))){
									
									List<AtributoCompuesto> listaAtributoCompuestosSegundoNivel = listaAtributoCompuestosPrimerNivel.get(i).getListaAtributosCompuestos();
									
									for(j=0; j<listaAtributoCompuestosSegundoNivel.size(); j++){
										if(listaAtributoCompuestosSegundoNivel.get(j).getNombre().equals(listaReferencia.get(5))){
											posicionAtributoCompuesto = j;
										}
									}
									
									listaAtributoCompuestosSegundoNivel.remove(posicionAtributoCompuesto);
								}
							}
						}
				
					}
				}
			}
		}
	}


	
	//elimina la jerarquia de la lista de jerarquias del diagrama
	private void eliminarJerarquia(){
	
		int posicion = -1;
		
		List<Jerarquia> listaJerarquias = controlProyecto.getDiagramaEnPantalla().getListaJerarquia();
		
		for(int i=0; i<listaJerarquias.size(); i++){
			Jerarquia jerarquia = listaJerarquias.get(i);
			
			if(jerarquia.getIdentificator().equals(nombreElemento)){
				posicion = i;
			}
		}
		
		
		if(posicion != -1) controlProyecto.getDiagramaEnPantalla().getListaJerarquia().remove(posicion);
	
	}
	


	public void setReference(String reference) {
		this.reference = reference;
		
	}

	
	
	
	

}
